package com.bestcem.xm.member.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.bestcem.xm.common.core.constant.AppRequestErrorCode;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.label.entity.pojo.LabelValueDO;
import com.bestcem.xm.label.service.LabelValueService;
import com.bestcem.xm.member.controller.param.*;
import com.bestcem.xm.member.controller.vo.*;
import com.bestcem.xm.member.enums.DeliveryTypeEnum;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.grpc.service.param.PageParam;
import com.bestcem.xm.member.grpc.service.param.member.CheckUserStorePermParam;
import com.bestcem.xm.member.grpc.service.param.member.ListContactMembersParam;
import com.bestcem.xm.member.service.ImportService;
import com.bestcem.xm.member.service.MemberQueryFieldService;
import com.bestcem.xm.member.service.MemberService;
import com.bestcem.xm.member.service.dto.*;
import com.bestcem.xm.member.service.param.ImportMemberParam;
import com.bestcem.xm.member.service.param.ImportProjectParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 联系人 controller
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/8/4
 */

@Slf4j
@RestController
@RequestMapping("/member/members")
public class MemberController {

    @Resource
    private MemberService memberService;

    @Resource
    private ImportService importService;

    @Resource
    private LabelValueService labelValueService;

    @Resource
    private MemberQueryFieldService memberQueryFieldService;

    /**
     * 查询企业个人联系人数量（激活的）
     *
     * @return 个人联系人数量
     */
    @GetMapping("/individual/count")
    public XmResultJson<IndividualCountVo> countIndividualMember(HttpServletRequest request) {
        // 获取组织id

        String orgId = SecurityContextHolder.getOrgId();
        ServiceResult<Long> result = memberService.countIndividualMember(orgId);
        if (!result.isSuccess()) {
            XmResultJson.fail(-1, result.getMsg());
        }
        return XmResultJson.success(new IndividualCountVo(result.getData()));
    }


    /**
     * 个人联系人创建
     *
     * @param param
     * @return
     */
    @PostMapping("/individual")
    public XmResultJson createIndividualMember(@Valid @RequestBody HttpCreateMemberParam param,
                                               HttpServletRequest request) {
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        param.setMemberType(MemberTypeEnum.INDIVIDUAL.getIndex());
        param.setOrgId(orgId);
        param.setUserId(userId);
        ServiceResult<String> result = memberService.createMember(param);
        if (result.isSuccess()) {
            CreateMemberVO vo = new CreateMemberVO();
            vo.setId(result.getData());
            return XmResultJson.success(vo);
        } else {
            if (StrUtil.isNotEmpty(result.getData())) {
                return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
            }
            return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
        }
    }

    /**
     * 机构联系人创建
     *
     * @param param
     * @return
     */
    @PostMapping("/institution")
    public XmResultJson createInstitutionMember(@Valid @RequestBody HttpCreateMemberParam param,
                                                HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        param.setMemberType(MemberTypeEnum.INSTITUTION.getIndex());
        param.setOrgId(orgId);
        param.setUserId(userId);
        ServiceResult<String> result = memberService.createMember(param);
        if (result.isSuccess()) {
            CreateMemberVO vo = new CreateMemberVO();
            vo.setId(result.getData());
            return XmResultJson.success(vo);
        } else {
            if (StrUtil.isNotEmpty(result.getData())) {
                return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
            }
            return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
        }
    }

    /**
     * 内部联系人创建
     *
     * @param param
     * @return
     */
    @PostMapping("/interior")
    public XmResultJson createInteriorMember(@Valid @RequestBody HttpCreateMemberParam param,
                                             HttpServletRequest request) {
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        param.setMemberType(MemberTypeEnum.INTERIOR.getIndex());
        param.setOrgId(orgId);
        param.setUserId(userId);
        ServiceResult<String> result = memberService.createMember(param);
        if (result.isSuccess()) {
            CreateMemberVO vo = new CreateMemberVO();
            vo.setId(result.getData());
            return XmResultJson.success(vo);
        } else {
            if (StrUtil.isNotEmpty(result.getData())) {
                return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
            }
            return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
        }
    }

    /**
     * 个人联系人批量创建
     *
     * @param params
     * @return
     */
    @PostMapping("/individuals")
    public XmResultJson createIndividualMembers(@RequestBody List<HttpCreateMemberParams> params,
                                                HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ServiceResult<CreateMembersDTO> result =
                memberService.createMembers(params, MemberTypeEnum.INDIVIDUAL.getIndex(), orgId, userId);
        CreateMembersDTO dto = result.getData();
        CreateMembersVO vo = new CreateMembersVO();
        if (ObjectUtil.isNotEmpty(dto)) {
            vo.setIds(dto.getIds());
            vo.setErrs(dto.getErrs());
        }
        return XmResultJson.success(vo);
    }

    /**
     * 机构联系人批量创建
     *
     * @param params
     * @return
     */
    @PostMapping("/institutions")
    public XmResultJson createInstitutionMembers(@RequestBody List<HttpCreateMemberParams> params,
                                                 HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ServiceResult<CreateMembersDTO> result =
                memberService.createMembers(params, MemberTypeEnum.INSTITUTION.getIndex(), orgId, userId);
        CreateMembersDTO dto = result.getData();
        CreateMembersVO vo = new CreateMembersVO();
        if (ObjectUtil.isNotEmpty(dto)) {
            vo.setIds(dto.getIds());
            vo.setErrs(dto.getErrs());
        }
        return XmResultJson.success(vo);
    }

    /**
     * 内部联系批量创建
     *
     * @param params
     * @return
     */
    @PostMapping("/interiors")
    public XmResultJson createInteriorMembers(@RequestBody List<HttpCreateMemberParams> params,
                                              HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ServiceResult<CreateMembersDTO> result =
                memberService.createMembers(params, MemberTypeEnum.INTERIOR.getIndex(), orgId, userId);
        CreateMembersDTO dto = result.getData();
        CreateMembersVO vo = new CreateMembersVO();
        if (ObjectUtil.isNotEmpty(dto)) {
            vo.setIds(dto.getIds());
            vo.setErrs(dto.getErrs());
        }
        return XmResultJson.success(vo);
    }


    /**
     * 联系人更新
     *
     * @param type
     * @param id
     * @param param
     * @return
     */
    @PutMapping("/{type}/{id}")
    public XmResultJson updateMember(@PathVariable String type,
                                     @PathVariable String id,
                                     @Valid @RequestBody HttpUpdateHttpMemberParam param,
                                     HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();

        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        switch (type) {
            case "individual":
                // 个人联系人
                param.setMemberType(MemberTypeEnum.INDIVIDUAL.getIndex());
                break;
            case "institution":
                // 机构联系人
                param.setMemberType(MemberTypeEnum.INSTITUTION.getIndex());
                break;
            case "interior":
                // 内部联系人
                param.setMemberType(MemberTypeEnum.INTERIOR.getIndex());
                break;
            default:
                return XmResultJson.fail(-1, "请求失败");
        }
        // 联系人Id
        param.setId(id);
        param.setOrgId(orgId);
        param.setUserId(userId);
        param.setSuperRole(tokenDTO.getSuperRole());
        param.setIsSenior(tokenDTO.getIsSenior());
        return memberService.updateMember(param);
    }

    /**
     * 获取联系人详情
     *
     * @param type
     * @param id
     * @return
     */
    @GetMapping("/{type}/{id}")
    public XmResultJson getMember(@PathVariable String type,
                                  @PathVariable String id,
                                  HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();

        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        switch (type) {
            case "individual":
            case "interior":
            case "institution":
                break;
            default:
                return XmResultJson.fail(-1, "请求失败");
        }
        ServiceResult<MemberDTO> result =
                memberService.getMemberDetail(id, orgId, userId, tokenDTO.getSuperRole(), tokenDTO.getIsSenior());
        if (!result.isSuccess()) {
            return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
        }
        MemberDTO data = result.getData();
        List<LabelValueIdDTO> labelValueIds = data.getLabelValueIds();
        MemberDetailVO vo = new MemberDetailVO();
        BeanUtil.copyProperties(data, vo);
        vo.setOid(vo.getId());
        if (CollUtil.isEmpty(vo.getAncestors())) {
            // 为空时赋初始值，以防前端报错
            vo.setAncestors(new ArrayList<>());
        }
        if (CollUtil.isEmpty(vo.getFieldValList())) {
            // 为空时赋初始值，以防前端报错
            vo.setFieldValList(new ArrayList<>());
        }
        if (CollUtil.isEmpty(vo.getFields())) {
            // 为空时赋初始值，以防前端报错
            vo.setFields(new ArrayList<>());
        }
        if (CollUtil.isNotEmpty(labelValueIds)) {
            // 开始处理标签
            List<String> ids = labelValueIds.stream()
                    .map(LabelValueIdDTO::getId).collect(Collectors.toList());
            List<LabelValueDO> labelValues = labelValueService.findById(ids);
            List<MemberLabelGroupVO> labels = buildLabels(labelValues);
            vo.setLabels(labels);
        }
        return XmResultJson.success(vo);
    }

    /**
     * 模糊查询个人联系人姓名、联系方式列表
     *
     * @param memberType   联系人类型
     * @param regex        关键字
     * @param deliveryType 投放类型
     * @param page         页数
     * @param pageSize     分页大小
     * @return XmResultJson<PageDTO < MemberDTO>>
     */
    @GetMapping("/{memberType}")
    public XmResultJson<PageDTO<DeliveryMemberVO>> fuzzySearchDeliveryMembers(@RequestParam(name = "mtype") Integer memberType,
                                                                              @RequestParam(name = "deliver_search", required = false) String regex,
                                                                              @RequestParam(name = "deliver_type", required = false) String deliveryType,
                                                                              @RequestParam(name = "page", required = false) Integer page,
                                                                              @RequestParam(name = "rowsPerPage", required = false) Integer pageSize,
                                                                              @RequestParam(name = "appid", required = false) String appId,
                                                                              HttpServletRequest request) {


        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();

        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        DeliveryTypeEnum deliveryTypeEnum = EnumUtil.getEnumByName(DeliveryTypeEnum.class, deliveryType);
        // 兼容前端分页参数
        PageParam pageParam = new PageParam(Optional.ofNullable(page).orElse(1), pageSize);

        ListContactMembersParam param = new ListContactMembersParam();
        param.setOrgId(orgId);
        param.setRegex(regex);
        param.setMemberTypeEnum(memberTypeEnum);
        param.setDeliveryTypeEnum(deliveryTypeEnum);
        param.setPageParam(pageParam);
        param.setUserId(userId);
        param.setSuperRole(tokenDTO.getSuperRole());
        param.setIsSenior(tokenDTO.getIsSenior());
        param.setAppId(appId);
        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            return XmResultJson.fail(-1, violation.getMessage());
        }

        if (deliveryTypeEnum.getIndex() == DeliveryTypeEnum.WX.getIndex()) {
            // 微信投放 appId 必须存在
            if (StrUtil.isBlank(appId)) {
                return XmResultJson.fail(-1, "微信投放,appId不能为空");
            }
        }
        ServiceResult<PageDTO<MemberDTO>> result = memberService.listMembers(param);
        if (!result.isSuccess()) {
            return XmResultJson.fail(-1, result.getMsg());
        }

        List<DeliveryMemberVO> data = new ArrayList<>(result.getData().getRows().size());
        // 兼容前端需求的特殊返回格式。
        for (MemberDTO m : result.getData().getRows()) {
            DeliveryMemberVO vo = this.convert(m);
            data.add(vo);
            if (DeliveryTypeEnum.EMAIL.equals(deliveryTypeEnum)) {
                vo.setName(vo.getName() + "(" + vo.getEmail() + ")");
            } else if (DeliveryTypeEnum.API.equals(deliveryTypeEnum)) {
                vo.setName(StrUtil.isBlank(vo.getName()) ? "" : vo.getName());
            } else if (DeliveryTypeEnum.WX.equals(deliveryTypeEnum)) {
                vo.setName(StrUtil.isBlank(vo.getName()) ? "" : vo.getName());
            } else {
                vo.setName(vo.getMobile() + "(" + vo.getMobile() + ")");
            }
        }
        return XmResultJson.success(new PageDTO<>(data, result.getData().getTotal()));
    }

    private DeliveryMemberVO convert(MemberDTO dto) {
        DeliveryMemberVO res = new DeliveryMemberVO();
        res.setId(dto.getId());
        res.setType(dto.getMemberType());
        res.setName(dto.getName());
        res.setRowName(dto.getName());
        res.setMobile(dto.getMobile());
        res.setEmail(dto.getEmail());
        res.setInstituteName(dto.getInstituteName());
        // 内部联系人 empolyeeId 其他联系人 out_no，且返回的empolyeeId命名为empolyeeID
        res.setOutNo(dto.getOutNo());
        res.setEmployeeId(dto.getEmployeeId());
        res.setOpenId(dto.getOpenId());
        res.setNickname(dto.getNickname());
        return res;
    }

    private List<MemberLabelGroupVO> buildLabels(List<LabelValueDO> labelValues) {
        if (CollUtil.isEmpty(labelValues)) {
            return new ArrayList<>();
        }

        // 根据标签组进行分组
        Map<String, List<LabelValueDO>> groupMap =
                labelValues.stream().collect(Collectors.groupingBy(LabelValueDO::getLabelGroupId));
        // 循环每一个标签组
        List<MemberLabelGroupVO> labelGroupVOS = new ArrayList<>(groupMap.size());
        groupMap.forEach((groupId, labels) -> {
            MemberLabelGroupVO vo = new MemberLabelGroupVO();
            vo.setId(groupId);
            // 标签组名称
            String labelGroupName = labels.get(0).getLabelGroupName();
            vo.setName(labelGroupName);
            // 标签 根据标签id进行分组
            Map<String, List<LabelValueDO>> labelMap =
                    labels.stream().collect(Collectors.groupingBy(LabelValueDO::getLabelId));
            List<MemberLabelVO> labelVOs = new ArrayList<>();
            labelMap.forEach((labelId, values) -> {
                MemberLabelVO memberLabelVO = new MemberLabelVO();
                memberLabelVO.setId(labelId);
                if (Objects.nonNull(values.get(0).getAuto())) {
                    memberLabelVO.setAuto(values.get(0).getAuto() == 1);
                }
                if (Objects.nonNull(values.get(0).getManual())) {
                    memberLabelVO.setManual(values.get(0).getManual() == 1);
                }
                memberLabelVO.setName(values.get(0).getLabelName());
                List<MemberLabelLabelVO> valueVOs = new ArrayList<>();
                values.forEach(value -> {
                    MemberLabelLabelVO memberLabelLabelVO = new MemberLabelLabelVO();
                    memberLabelLabelVO.setId(value.getLabelValueId());
                    memberLabelLabelVO.setName(value.getValue());
                    memberLabelLabelVO.setSerial(value.getSeq());
                    valueVOs.add(memberLabelLabelVO);
                });
                memberLabelVO.setValues(valueVOs);
                labelVOs.add(memberLabelVO);
            });
            vo.setLabels(labelVOs);
            labelGroupVOS.add(vo);
        });
        return labelGroupVOS;
    }

    /**
     * 联系人批量删除
     *
     * @param type
     * @param param
     * @return
     */
    @DeleteMapping("/{type}")
    public XmResultJson deleteMember(@PathVariable String type,
                                     @Valid @RequestBody HttpDeleteMembersParam param,
                                     HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();

        TokenDTO token = SecurityContextHolder.getToken();
        param.setOrgId(orgId);
        param.setUserId(userId);
        param.setIsSenior(token.getIsSenior());
        param.setSuperRole(token.getSuperRole());
        ServiceResult<Integer> result = memberService.deleteMembers(param);
        return XmResultJson.success(null, result.getMsg());
    }

    /**
     * 个人联系人导入
     *
     * @param nullUpdate
     * @param existedUpdate
     * @param primaryKey
     * @param files
     * @param type
     * @return
     */
    @PostMapping("/ind/import")
    public XmResultJson indMemberImport(@RequestParam(value = "null_update", required = false) Boolean nullUpdate,
                                        @RequestParam(value = "existed_update", required = false) Boolean existedUpdate,
                                        @RequestParam(value = "primary_key", required = false) String primaryKey,
                                        @RequestParam(value = "files", required = false) MultipartFile files,
                                        @RequestParam("member_type") Integer type,
                                        HttpServletRequest request) {


        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ImportMemberParam importMemberParam = buildImportMemberParam(MemberTypeEnum.INDIVIDUAL.getIndex(), orgId, files, userId, type);
        return memberImport(importMemberParam, primaryKey, nullUpdate, existedUpdate);
    }

    /**
     * 机构联系人导入
     *
     * @param nullUpdate
     * @param existedUpdate
     * @param primaryKey
     * @param files
     * @param type
     * @return
     */
    @PostMapping("/ins/import")
    public XmResultJson insMemberImport(@RequestParam(value = "null_update", required = false) Boolean nullUpdate,
                                        @RequestParam(value = "existed_update", required = false) Boolean existedUpdate,
                                        @RequestParam(value = "primary_key", required = false) String primaryKey,
                                        @RequestParam(value = "files", required = false) MultipartFile files,
                                        @RequestParam("member_type") Integer type,
                                        HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ImportMemberParam importMemberParam = buildImportMemberParam(MemberTypeEnum.INSTITUTION.getIndex(), orgId, files, userId, type);
        return memberImport(importMemberParam, primaryKey, nullUpdate, existedUpdate);
    }

    /**
     * 内部联系人导入
     *
     * @param nullUpdate
     * @param existedUpdate
     * @param primaryKey
     * @param files
     * @param type
     * @return
     */
    @PostMapping("/int/import")
    public XmResultJson intMemberImport(@RequestParam(value = "null_update", required = false) Boolean nullUpdate,
                                        @RequestParam(value = "existed_update", required = false) Boolean existedUpdate,
                                        @RequestParam(value = "primary_key", required = false) String primaryKey,
                                        @RequestParam(value = "files", required = false) MultipartFile files,
                                        @RequestParam("member_type") Integer type,
                                        HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ImportMemberParam importMemberParam = buildImportMemberParam(MemberTypeEnum.INTERIOR.getIndex(), orgId, files, userId, type);
        return memberImport(importMemberParam, primaryKey, nullUpdate, existedUpdate);
    }

    /**
     * 构建导入参数
     *
     * @param memberType
     * @param orgId
     * @param files
     * @param userId
     * @param type
     * @return
     */
    private ImportMemberParam buildImportMemberParam(int memberType, String orgId, MultipartFile files,
                                                     String userId, Integer type) {

        ImportMemberParam importMemberParam = new ImportMemberParam();
        importMemberParam.setAttribute(memberType);
        importMemberParam.setOrgId(orgId);
        importMemberParam.setFiles(files);
        importMemberParam.setUserId(userId);
        importMemberParam.setType(type);
        return importMemberParam;
    }

    /**
     * 联系人导入
     *
     * @param importMemberParam
     * @param primaryKey
     * @param nullUpdate
     * @param existedUpdate
     * @return
     */
    private XmResultJson memberImport(ImportMemberParam importMemberParam, String primaryKey, Boolean nullUpdate, Boolean existedUpdate) {
        if (StrUtil.isEmpty(primaryKey)) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_LOST, "primary_key参数缺失");
        }
        importMemberParam.setPrimaryKey(primaryKey);
        if (ObjectUtil.isEmpty(nullUpdate)) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_LOST, "null_update参数缺失");
        }
        importMemberParam.setNullUpdate(nullUpdate);
        if (ObjectUtil.isEmpty(existedUpdate)) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_LOST, "existedUpdate参数缺失");
        }
        importMemberParam.setExistedUpdate(existedUpdate);
        ServiceResult<String> result = importService.importMembers(importMemberParam);
        if (result.isSuccess()) {
            ImportVO vo = new ImportVO();
            vo.setImportRecordId(result.getData());
            return XmResultJson.success(vo);
        }
        return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getMsg());
    }

    /**
     * 项目导入
     *
     * @param nullUpdate
     * @param existedUpdate
     * @param files
     * @param type
     * @return
     */
    @PostMapping("/mp/import")
    public XmResultJson mProjectImport(@RequestParam(value = "null_update", required = false) Boolean nullUpdate,
                                       @RequestParam(value = "existed_update", required = false) Boolean existedUpdate,
                                       @RequestParam(value = "files", required = false) MultipartFile files,
                                       @RequestParam("member_type") Integer type,
                                       HttpServletRequest request) {
        // 获取orgId

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        ImportProjectParam param = new ImportProjectParam();
        param.setOrgId(orgId);
        param.setUserId(userId);
        if (ObjectUtil.isEmpty(nullUpdate)) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_LOST, "null_update参数缺失");
        }
        param.setNullUpdate(nullUpdate);
        if (ObjectUtil.isEmpty(existedUpdate)) {
            return XmResultJson.fail(AppRequestErrorCode.PARAM_LOST, "existedUpdate参数缺失");
        }
        param.setExistedUpdate(existedUpdate);
        param.setImportType(type);
        param.setFiles(files);
        ServiceResult<String> result = importService.importProjects(param);
        if (result.isSuccess()) {
            ImportVO vo = new ImportVO();
            vo.setImportRecordId(result.getData());
            return XmResultJson.success(vo);
        }
        return XmResultJson.fail(Integer.parseInt(result.getErrorCode()), result.getData());
    }

    /**
     * 获取联系人查询字段
     *
     * @param attribute
     * @return
     */
    @GetMapping("/queryField")
    public XmResultJson getQueryField(@RequestParam(value = "attribute", required = false) Integer attribute,
                                      HttpServletRequest request) {
        if (ObjectUtil.isEmpty(attribute)) {
            attribute = 0;
        }

        String orgId = SecurityContextHolder.getOrgId();
        ServiceResult<MemberQueryFieldDTO> result =
                memberQueryFieldService.getQueryField(attribute, orgId);
        return XmResultJson.success(result.getData());
    }

    /**
     * 更新联系人查询字段
     * 若不存在id 则是插入
     *
     * @param param
     * @return
     */
    @PostMapping("/queryField")
    public XmResultJson updateQueryField(@RequestBody HttpUpdateQueryFieldParam param,
                                         HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();
        param.setOrgId(orgId);
        if (ObjectUtil.isEmpty(param.getAttribute())) {
            param.setAttribute(MemberTypeEnum.INDIVIDUAL.getIndex());
        }
        ServiceResult<String> result = memberQueryFieldService.updateQueryField(param);
        return XmResultJson.success(result.getData());
    }

    /**
     * 按联系人名称模糊搜索联系人
     *
     * @param memberType 联系人类型
     * @param nameRegex  联系人名称模糊查询参数
     * @param page       分页参数页数 默认 1
     * @param pageSize   分页参数单页大小 默认 10
     * @param request    http 请求
     * @return 联系人分页列表
     */
    @GetMapping("/name_search")
    public XmResultJson<PageDTO<MemberVO>> listMembersByRegexName(
            @RequestParam(name = "member_type", required = false) Integer memberType,
            @RequestParam(name = "search", required = false) String nameRegex,
            @RequestParam(name = "page", required = false) Integer page,
            @RequestParam(name = "rowsPerPage", required = false) Integer pageSize,
            HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        // token获取用户id

        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }

        // 联系人类型
        MemberTypeEnum memberTypeEnum = EnumUtil.getEnumByIndex(MemberTypeEnum.class, memberType);
        // 分页参数，默认
        com.bestcem.xm.member.grpc.service.param.PageParam pageParam = new com.bestcem.xm.member.grpc.service.param.PageParam(Optional.ofNullable(page).orElse(1) - 1, Optional.ofNullable(pageSize).orElse(10));

        ServiceResult<PageDTO<MemberDTO>> result = memberService.listByNameRegex(orgId, userId, memberTypeEnum,
                nameRegex, pageParam, tokenDTO.getSuperRole(), tokenDTO.getIsSenior());
        if (!result.isSuccess()) {
            if (log.isErrorEnabled()) {
                log.error("查询联系人失败：{}", result.getMsg());
            }
            return XmResultJson.fail(-1, result.getMsg());
        }

        PageDTO<MemberDTO> pageDTO = result.getData();
        List<MemberVO> memberVos = pageDTO.getRows().stream().map(this::convertMemberVo).collect(Collectors.toList());

        return XmResultJson.success(new PageDTO<>(memberVos, pageDTO.getTotal()));
    }

    /**
     * @return
     */
    @GetMapping("/store_check")
    public XmResultJson<Boolean> storeCheck(
            @RequestParam(name = "store_id", required = false) String storeId,
            HttpServletRequest request) {

        String orgId = SecurityContextHolder.getOrgId();

        String userId = SecurityContextHolder.getUserId();
        // token获取用户id

        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        if (log.isInfoEnabled()) {
            log.info("orgId: {}", orgId);
            log.info("userId: {}", userId);
        }

        CheckUserStorePermParam param = new CheckUserStorePermParam();
        param.setOrgId(orgId);
        param.setUserId(userId);
        param.setStoreId(storeId);
        param.setSuperRole(tokenDTO.getSuperRole());
        param.setIsSenior(tokenDTO.getIsSenior());
        ServiceResult<Boolean> result =
                memberService.checkUserStorePermission(param);
        if (!result.isSuccess()) {
            if (log.isErrorEnabled()) {
                log.error("查询联系人失败：{}", result.getMsg());
            }
            return XmResultJson.fail(-1, result.getMsg());
        }
        return XmResultJson.success(result.getData());
    }

    private MemberVO convertMemberVo(MemberDTO dto) {
        MemberVO vo = new MemberVO();
        vo.setId(dto.getId());
        vo.setName(dto.getName());
        vo.setMemberType(dto.getMemberType());
        vo.setPhone(dto.getMobile());
        vo.setEmail(dto.getEmail());
        return vo;
    }
}
